// Copyright (C) 1953-2023 NUDT
// Verilog module name - network_buffer_input   
// Version: V4.3.0.20230309
// Created:
//         by - fenglin 
////////////////////////////////////////////////////////////////////////////
// Description:
//         Network receive process
///////////////////////////////////////////////////////////////////////////

`timescale 1ns/1ps

module network_buffer_input  #(parameter inport = 6'b0000,forward_mode = 1'b0) //forward_mode:0,cutthrough; 1,stored  
    (
        i_clk,
        i_rst_n,
        
        i_data_wr,
        iv_data,
        
        iv_addr             ,      
        iv_wdata            ,
        i_wr_psc            ,
        i_rd_psc            ,
        i_wr_pdg            ,
        i_rd_pdg            ,
                                     
        o_wr_psc            ,
        ov_addr_psc         ,
        ov_rdata_psc        ,                                       
        o_wr_pdg            ,
        ov_addr_pdg         ,
        ov_rdata_pdg        ,
                          
        i_rc_rxenable                   ,
        i_st_rxenable                   ,
        i_hardware_initial_finish,

        i_pkt_bufid_wr      ,
        iv_pkt_bufid        ,
        o_pkt_bufid_ack     ,
        
        ov_desp             ,
        o_desp_wr           ,
        //ov_eth_type         ,
        //ov_tsmp_subtype     ,
        
        ov_pkt,
        o_pkt_wr,
        ov_pkt_bufadd,
        i_pkt_ack,
        
        iv_free_bufid_num,
        iv_hpriority_be_threshold_value,
        iv_rc_threshold_value,
        iv_lpriority_be_threshold_value
    );

// I/O
// clk & rst
input                   i_clk;
input                   i_rst_n;
//GMII RX input
input                   i_data_wr;
input       [8:0]       iv_data ;

input       [18:0]      iv_addr;                         
input       [31:0]      iv_wdata;                        
input                   i_wr_psc;         
input                   i_rd_psc;         
input                   i_wr_pdg;                        
input                   i_rd_pdg; 

output                  o_wr_psc;          
output     [18:0]       ov_addr_psc;       
output     [31:0]       ov_rdata_psc; 

output                  o_wr_pdg;                     
output     [18:0]       ov_addr_pdg;                  
output     [31:0]       ov_rdata_pdg; 
//configuration
input                   i_hardware_initial_finish;
input                   i_rc_rxenable                   ;
input                   i_st_rxenable                   ;
//pkt bufid input
input                   i_pkt_bufid_wr;
input       [8:0]       iv_pkt_bufid;
output                  o_pkt_bufid_ack;
//descriptor output
output      [35:0]      ov_desp    ;
output                  o_desp_wr  ;
//output      [15:0]      ov_eth_type;
//output      [7:0]       ov_tsmp_subtype;
//user data output
output      [133:0]     ov_pkt;
output                  o_pkt_wr;
output      [15:0]      ov_pkt_bufadd;
input                   i_pkt_ack;

input       [8:0]       iv_free_bufid_num;
input       [8:0]       iv_hpriority_be_threshold_value;
input       [8:0]       iv_rc_threshold_value;
input       [8:0]       iv_lpriority_be_threshold_value;
// internal wire
wire        [8:0]       wv_data_psc2dex     ;
wire                    w_data_wr_psc2dex   ;
wire        [15:0]      wv_eth_type_psc2dex ;
wire        [2:0]       wv_ipv_psc2dex;

wire        [133:0]     wv_pkt_pdg2ibi;
wire                    w_pkt_wr_pdg2ibi;
wire        [8:0]       wv_pkt_bufid_pdg2ibi;
wire                    w_pkt_bufid_wr_pdg2ibi; 

wire                    w_pkt_write_finish_ibi2pdg;
  
(*MARK_DEBUG="true"*) reg  [31:0]  rv_pkt_cnt_nip_psc2pdg;
(*MARK_DEBUG="true"*) reg   data_valid_delay_nip_psc2pdg;
always @(posedge i_clk or negedge i_rst_n) begin
    if (!i_rst_n) begin
        rv_pkt_cnt_nip_psc2pdg <= 32'b0;
		data_valid_delay_nip_psc2pdg    <=  1'b0;
    end
    else begin
	    data_valid_delay_nip_psc2pdg <= w_data_wr_psc2dex;
        if((!data_valid_delay_nip_psc2pdg) && w_data_wr_psc2dex)begin
			rv_pkt_cnt_nip_psc2pdg <= rv_pkt_cnt_nip_psc2pdg + 1'b1;
        end
        else begin
            rv_pkt_cnt_nip_psc2pdg <=  rv_pkt_cnt_nip_psc2pdg;
        end		
	end	
end 

port_state_control port_state_control_inst(
.i_clk                            (i_clk                          ),
.i_rst_n                          (i_rst_n                        ),

.i_rc_rxenable                    (i_rc_rxenable                    ),
.i_st_rxenable                    (i_st_rxenable                    ),
.i_hardware_initial_finish        (i_hardware_initial_finish      ),                                                          
.i_data_wr                        (i_data_wr                   ),
.iv_data                          (iv_data                    ),
                                                                
.iv_addr                          (iv_addr                        ),                         
.iv_wdata                         (iv_wdata                       ),                        
.i_wr_irx                         (i_wr_psc                       ),         
.i_rd_irx                         (i_rd_psc                       ),         
                                                                  
.o_wr_irx                         (o_wr_psc                       ),         
.ov_addr_irx                      (ov_addr_psc                    ),      
.ov_rdata_irx                     (ov_rdata_psc                   ), 

.ov_data                          (wv_data_psc2dex                ),
.o_data_wr                        (w_data_wr_psc2dex              ),
.ov_eth_type                      (wv_eth_type_psc2dex            ),
.ov_ipv                           (wv_ipv_psc2dex )
);    
   //#(parameter network_port_or_hcp_port = 1'b0)//1'b0:network port.   1'b1:hcp port.    
packet_descriptor_generate #(.inport(inport),.forward_mode(forward_mode)) packet_descriptor_generate_inst(
.i_clk          (i_clk),
.i_rst_n        (i_rst_n),

.iv_addr        (iv_addr),                         
.iv_wdata       (iv_wdata),                            
.i_wr_pdg       (i_wr_pdg),                        
.i_rd_pdg       (i_rd_pdg), 

.o_wr_pdg       (o_wr_pdg),                     
.ov_addr_pdg    (ov_addr_pdg),                  
.ov_rdata_pdg   (ov_rdata_pdg), 

.iv_data        (wv_data_psc2dex),
.i_data_wr      (w_data_wr_psc2dex),
.iv_eth_type    (wv_eth_type_psc2dex),
.iv_ipv         (wv_ipv_psc2dex),

.i_pkt_bufid_wr (i_pkt_bufid_wr),
.iv_pkt_bufid   (iv_pkt_bufid),
.o_pkt_bufid_ack(o_pkt_bufid_ack),

.ov_pkt         (wv_pkt_pdg2ibi),
.o_pkt_wr       (w_pkt_wr_pdg2ibi),
.o_pkt_bufid_wr (w_pkt_bufid_wr_pdg2ibi),
.ov_pkt_bufid   (wv_pkt_bufid_pdg2ibi),

.ov_descriptor  (ov_desp        ),
.o_descriptor_wr(o_desp_wr      ),
//.ov_eth_type    (ov_eth_type    ),
//.ov_tsmp_subtype(ov_tsmp_subtype),

.i_pkt_write_finish(w_pkt_write_finish_ibi2pdg),

.iv_hardware_stage               (3'b0),
.iv_free_bufid_num               (iv_free_bufid_num      ),
.iv_hpriority_be_threshold_value (iv_hpriority_be_threshold_value ),
.iv_rc_threshold_value           (iv_rc_threshold_value           ),
.iv_lpriority_be_threshold_value (iv_lpriority_be_threshold_value )       
);

input_buffer_interface  input_buffer_interface_inst(
.i_clk          (i_clk),
.i_rst_n        (i_rst_n),
.i_pkt_wr       (w_pkt_wr_pdg2ibi),
.iv_pkt         (wv_pkt_pdg2ibi),
.i_pkt_bufid_wr (w_pkt_bufid_wr_pdg2ibi),
.iv_pkt_bufid   (wv_pkt_bufid_pdg2ibi),
.ov_pkt         (ov_pkt),
.o_pkt_wr       (o_pkt_wr),
.ov_pkt_bufadd  (ov_pkt_bufadd),
.i_pkt_ack      (i_pkt_ack),
.o_pkt_write_finish(w_pkt_write_finish_ibi2pdg),
.input_buf_interface_state()
);
endmodule